package com.health.healthproject.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.health.healthproject.common.Result;
import com.health.healthproject.dto.AnnouncementDTO;
import com.health.healthproject.entity.Announcement;
import com.health.healthproject.mapper.AnnouncementMapper;
import com.health.healthproject.service.AnnouncementService;
import com.health.healthproject.util.FileUploadUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Service
public class AnnouncementServiceImpl extends ServiceImpl<AnnouncementMapper, Announcement> implements AnnouncementService {

    @Resource
    private AnnouncementMapper mapper;
    @Qualifier("announcementMapper")
    @Autowired
    private AnnouncementMapper announcementMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AnnouncementDTO createAnnouncement(AnnouncementDTO announcementDTO, List<MultipartFile> attachments) throws IOException {
        // 处理附件上传
        List<String> attachmentPaths = new ArrayList<>();
        if (!CollectionUtils.isEmpty(attachments)) {
            attachmentPaths = FileUploadUtil.uploadFiles(attachments, FileUploadUtil.BusinessType.ANNOUNCEMENT);
        }
        // 设置创建者和更新者
        Long userId = StpUtil.getLoginIdAsLong();
        // 更新
        if (announcementDTO.getId() != null && announcementDTO.getId() >0){
            if (StringUtils.isNotBlank(announcementDTO.getFileName())){
                attachmentPaths.addAll(Arrays.asList(announcementDTO.getFileName().split(";")));
            }
            announcementDTO.setUpdateBy(userId);
        }else{
            // 新增
            announcementDTO.setCreateBy(userId);
            announcementDTO.setUpdateBy(userId);
            announcementDTO.setStatus(1);
        }
        // 保存公告
        announcementDTO.setAttachments(attachmentPaths);
        Announcement announcement = announcementDTO.toEntity();
        if (announcement.getId() != null && announcement.getId() >0){
            mapper.updateById(announcement);
        }else{
            save(announcement);
        }
        return AnnouncementDTO.fromEntity(announcement);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AnnouncementDTO updateAnnouncement(AnnouncementDTO announcementDTO, List<MultipartFile> attachments) throws IOException {
        // 获取原有公告
        Announcement existingAnnouncement = getById(announcementDTO.getId());
        if (existingAnnouncement == null) {
            throw new IllegalArgumentException("公告不存在");
        }

        // 只有草稿状态的公告可以修改
        if (!Objects.equals(existingAnnouncement.getStatus(), Announcement.Status.DRAFT)) {
            throw new IllegalStateException("只有草稿状态的公告可以修改");
        }

        // 处理新上传的附件
        if (!CollectionUtils.isEmpty(attachments)) {
            List<String> newAttachmentPaths = FileUploadUtil.uploadFiles(attachments, FileUploadUtil.BusinessType.ANNOUNCEMENT);
            // 合并原有附件和新附件
            List<String> allAttachments = existingAnnouncement.getAttachmentList();
            allAttachments.addAll(newAttachmentPaths);
            announcementDTO.setAttachments(allAttachments);
        }

        // 设置更新者
        announcementDTO.setUpdateBy(StpUtil.getLoginIdAsLong());

        // 保持原状态不变
        announcementDTO.setStatus(existingAnnouncement.getStatus());

        // 更新公告
        Announcement announcement = announcementDTO.toEntity();
        updateById(announcement);

        return AnnouncementDTO.fromEntity(announcement);
    }

    @Override
    public AnnouncementDTO getAnnouncement(Long id) {
        return AnnouncementDTO.fromEntity(getById(id));
    }

    @Override
    public Page<AnnouncementDTO> listAnnouncements(Integer status,String title,Long userId,String startTime,String endTime, Page<AnnouncementDTO> page) {

        return mapper.selectByPage(page,status,title,userId,startTime,endTime);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishAnnouncement(Long id) {
        Announcement announcement = getById(id);
        if (announcement == null) {
            throw new IllegalArgumentException("公告不存在");
        }

        if (!Objects.equals(announcement.getStatus(), Announcement.Status.DRAFT)) {
            throw new IllegalStateException("只有草稿状态的公告可以发布");
        }

        announcement.setStatus(Announcement.Status.PUBLISHED);
        announcement.setUpdateBy(StpUtil.getLoginIdAsLong());
        updateById(announcement);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recallAnnouncement(Long id) {
        Announcement announcement = getById(id);
        if (announcement == null) {
            throw new IllegalArgumentException("公告不存在");
        }

        if (!Objects.equals(announcement.getStatus(), Announcement.Status.PUBLISHED)) {
            throw new IllegalStateException("只有已发布的公告可以撤回");
        }

        announcement.setStatus(Announcement.Status.RECALLED);
        announcement.setUpdateBy(StpUtil.getLoginIdAsLong());
        updateById(announcement);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAnnouncement(Long id) {
        Announcement announcement = mapper.selectById(id);
        if (announcement == null) {
            throw new IllegalArgumentException("公告不存在");
        }
        announcement.setStatus(0);
        updateById(announcement);
    }

    @Override
    public Result<List<AnnouncementDTO>> latest() {
        List<AnnouncementDTO> result =  announcementMapper.selectLatest();
        return Result.success(result);
    }
}